#include "StdAfx.h"
#include "DxfLine.h"
#include <math.h>
#include <float.h>

DxfPoint::DxfPoint(double px/*=0.0*/, double py/*=0.0*/, double pz/*=0.0*/)
: DL_PointData(px, py, pz)
{

}

DxfPoint::DxfPoint(const DxfPoint& pointData)
: DL_PointData(pointData.x, pointData.y, pointData.z)
{

}

DxfPoint::~DxfPoint( void )
{

}

DxfPoint& DxfPoint::operator=( const DxfPoint& pointData )
{
    x = pointData.x;
    y = pointData.y;
    z = pointData.z;

    return *this;
}

double DxfPoint::Angle()
{
    return RelativeAngle(DxfPoint(0.0, 0.0));
}

double DxfPoint::RelativeDistance(const DxfPoint& referPoint)
{
    return sqrt(pow((x - referPoint.x), 2) + pow((y - referPoint.y), 2));
}

double DxfPoint::RelativeAngle(const DxfPoint& referPoint)
{
    return atan2(y - referPoint.y, x - referPoint.x) * 180 / M_PI;
}

DxfPoint DxfPoint::Translate( double tx, double ty )
{
    return DxfPoint(x + tx, y + ty);
}

DxfPoint DxfPoint::Rotate(double angle)
{
    double radian = (angle * M_PI) / 180;
    double x0 = (x) * cos(radian) - (y)*sin(radian);
    double y0 = (x) * sin(radian) + (y)*cos(radian);

    return DxfPoint(x0, y0);
}

DxfLine::DxfLine( const DxfPoint& p1, const DxfPoint& p2 )
: DL_LineData(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z),
  cutterType(1)
{
    
}


DxfLine::DxfLine( double dx1, double dy1, double dx2, double dy2 )
: DL_LineData(dx1, dy1, 0.0, dx2, dy2, 0.0),
  cutterType(1)
{
    
}

DxfLine::DxfLine( double dx1, double dy1, double dz1, double dx2, double dy2, double dz2 )
: DL_LineData(dx1, dy1, dz1, dx2, dy2, dz2),
  cutterType(1)
{
    
}

DxfLine::~DxfLine(void)
{
}

DxfLine::DxfLine(const DxfLine& lineData)
{
    x1 = lineData.x1;
    y1 = lineData.y1;
    z1 = lineData.z1;

    x2 = lineData.x2;
    y2 = lineData.y2;
    z2 = lineData.z2;

    cutterType = lineData.cutterType;
}


DxfLine& DxfLine::operator = (const DxfLine& lineData)
{
    x1 = lineData.x1;
    y1 = lineData.y1;
    z1 = lineData.z1;

    x2 = lineData.x2;
    y2 = lineData.y2;
    z2 = lineData.z2;

    cutterType = lineData.cutterType;

    return *this;
}

int DxfLine::operator == (const DxfLine& lineData)
{
    return fabs(x1 - lineData.x1 ) < DBL_EPSILON
        && fabs(y1 - lineData.y1 ) < DBL_EPSILON
        && fabs(z1 - lineData.z1 ) < DBL_EPSILON
        && fabs(x2 - lineData.x2 ) < DBL_EPSILON
        && fabs(y2 - lineData.y2 ) < DBL_EPSILON
        && fabs(z2 - lineData.z2 ) < DBL_EPSILON;
}

double DxfLine::Length()
{
    return sqrt(pow((x1 - x2), 2) + pow((y1 - y2), 2));
}

DxfPoint DxfLine::Point1()
{
    return DxfPoint(x1, y1, z1);
}

DxfPoint DxfLine::Point2()
{
    return DxfPoint(x2, y2, z2);
}

double DxfLine::Angle()
{
    return atan((y2 - y1) / (x2 - x1)) * 180 / M_PI;
}

double DxfLine::RotativeAngle()
{
    DxfPoint p1 = Point1();
    DxfPoint p2 = Point2();

    double angle = 0;
    if (fabs(p2.x - p1.x) < DBL_EPSILON)
    {
        angle = 0;
    }
    else
    {
        angle = Angle();
        if (p1.x < 0)
        {
            angle = 90 - angle;
        }
        else
        {
            angle = -(90 + angle);
        }
    }

    return angle;
}

DxfLine DxfLine::Translate(double tx, double ty)
{
    return DxfLine(x1 + tx, y1 + ty, x2 + tx, y2 + ty);
}

DxfLine DxfLine::Rotate( double angle )
{
    return DxfLine(Point1().Rotate(angle), Point2().Rotate(angle));
}

DxfLine DxfLine::Zoom( double zoomX, double zoomY )
{
    return DxfLine(x1 * zoomX, y1 * zoomY, x2 * zoomX, y2 * zoomY);
}

DxfPoint DxfLine::CentrePoint()
{
    return DxfPoint((x1 + x2) / 2, (y1 + y2) / 2);
}


